import {
  HttpClient,
  HttpHeaders,
  HttpErrorResponse,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpEvent,
  HttpResponse,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError, from } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import Setting from '../../config';
import { Router } from '@angular/router';
import { ToastController } from '@ionic/angular';
import { TOKEN } from '../constant';
import { UtilsService } from '../utils.service';

@Injectable({
  providedIn: 'root',
})
export class RequestService implements HttpInterceptor {
  token: any;
  headers: HttpHeaders;
  constructor(
    private http: HttpClient,
    private router: Router,
    private toast: ToastController,
    private utils: UtilsService,
  ) {
    // this.headers = new HttpHeaders({
    //     token: localStorage.getItem('token') ? localStorage.getItem('token') : '',
    // });
  }
  // 基础路径
  public baseUrl = Setting.baseUrl;

  /**
   * get请求处理
   * @param url api地址
   * @param params Object
   */
  public get(url: string, params?: object): Observable<any> {
    const _this = this;
    const item: string = this.getParamsFormatter(params);
    return this.http
      .get(`${this.baseUrl}${url}${item}`, {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'X-Access-Token': String(localStorage.getItem(TOKEN)),
        }),
      })
      .pipe(
        map(this.extractData),
        catchError((value) => this.handleError(value, _this)),
      );
  }

  /**
   * post请求处理
   * @param url api地址
   * @param data object
   */
  public post(url: string, data: object): Observable<any> {
    return this.http.post(`${this.baseUrl}${url}`, data, {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'X-Access-Token': String(localStorage.getItem(TOKEN)),
      }),
    });
  }

  /**
   * put请求
   * @param url api地址
   * @param data object
   */
  public put(url: string, data = {}): Observable<any> {
    return this.http
      .put(`${this.baseUrl}${url}`, data, {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'X-Access-Token': String(localStorage.getItem(TOKEN)),
        }),
      })
      .pipe(map(this.extractData), catchError(this.handleError));
  }

  /**
   * delete请求
   * @param url api地址
   */
  public delete(url: string): Observable<any> {
    return this.http
      .delete(`${this.baseUrl}${url}`, {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'X-Access-Token': String(localStorage.getItem(TOKEN)),
        }),
      })
      .pipe(map(this.extractData), catchError(this.handleError));
  }

  /**
   * 提取数据
   * @param res 返回结果
   */
  private extractData(res: Response) {
    const body = res;
    return body || {};
  }

  /**
   * 错误消息类
   * @param error 错误
   */
  private handleError(error: HttpErrorResponse, _this?: any) {
    console.log(error, '错误信息');
    console.log(_this);
    if (error.status === 500) {
      if (error.error.message === 'Token失效，请重新登录') {
        console.log('请重新登录！');
        _this.utils.showToast('登录失效,请重新登录!', 'top');
        localStorage.clear();
        _this.router.navigateByUrl('/login');
      }
    }
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
    }
    return throwError('Something bad happened; please try again later.');
  }

  /**
   * get方式过滤自动拼接数据
   * @ param val
   */
  private getParamsFormatter(val: object) {
    if (typeof val === 'object') {
      let item = '?';
      // tslint:disable-next-line:forin
      // @ts-ignore
      // tslint:disable-next-line:forin
      for (const n: string in val) {
        item += `${n}=${val[n]}&`;
      }
      return item.substring(0, item.length - 1);
    }
    return '';
  }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // const token = localStorage.getItem(TOKEN) ? localStorage.getItem(TOKEN) : '';
    // if (token) {
    //   request = request.clone({
    //     headers: request.headers.set('X-Access-Token', token),
    //   });
    // }
    // if (!request.headers.has('Content-Type')) {
    //   request = request.clone({
    //     headers: request.headers.set('Content-Type', 'application/json'),
    //   });
    // }
    request = request.clone({
      headers: request.headers.set('Accept', 'application/json'),
    });
    return next.handle(request).pipe(
      map((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          // console.log(event, '当前的状态值');
          switch (event.body.code) {
            case 401:
              this.showToast('登录失效!');
              localStorage.removeItem('token');
              this.router.navigateByUrl('/login');
              break;
            case 500:
              console.log('错误');
              break;
          }
        }
        return event;
      }),
    );
  }

  async showToast(title: string) {
    const toast = await this.toast.create({
      message: title,
      duration: 2000,
      position: 'top',
      cssClass: 'commonToast',
    });
    await toast.present();
  }
}
